package com.bzkj.system.service.impl;

import com.bzkj.common.core.domain.AjaxResult;
import com.bzkj.common.core.page.TableDataInfo;
import com.bzkj.msfx.utils.FusionHttpUtils;
import com.bzkj.system.domain.SysOperOrderLog;
import com.bzkj.system.mapper.SysOperOrderLogMapper;
import com.bzkj.system.service.ISysOperOrderLogService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 操作日志 服务层处理
 *
 * @author ruoyi
 */
@Service
public class SysOperOrderLogServiceImpl implements ISysOperOrderLogService {
    @Autowired
    private SysOperOrderLogMapper operLogMapper;

    @Resource
    private FusionHttpUtils fusionHttpUtils;

    /**
     * 新增操作日志
     *
     * @param operLog 操作日志对象
     */
    @Override
    public Long insertOperlog(SysOperOrderLog operLog) {
        operLogMapper.insertOperlog(operLog);
        return operLog.getOperId();
    }

    /**
     * 查询系统操作日志集合
     *
     * @param operLog 操作日志对象
     * @return 操作日志集合
     */
    @Override
    public List<SysOperOrderLog> selectOperLogList(SysOperOrderLog operLog) {
        return operLogMapper.selectOperLogList(operLog);
    }

    /**
     * 查询系统操作日志集合（导出）
     *
     * @param operLog 操作日志对象
     * @return 操作日志集合
     */
    @Override
    public List<SysOperOrderLog> selectOperLogListExport(SysOperOrderLog operLog) {
        List<SysOperOrderLog> sysOperOrderLogs = operLogMapper.selectOperLogList(operLog);
        try {
            for (SysOperOrderLog sysOperOrderLog : sysOperOrderLogs) {
                String operationDetail = sysOperOrderLog.getOperationDetail();
                if (operationDetail != null && !operationDetail.isEmpty()) {
                    String parseJson = parseJson(operationDetail);
                    sysOperOrderLog.setOperationDetail(parseJson);
                }
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException("解析JSON字符串失败", e);
        }

        return sysOperOrderLogs;
    }


    /**
     * 批量删除系统操作日志
     *
     * @param operIds 需要删除的操作日志ID
     * @return 结果
     */
    @Override
    public int deleteOperLogByIds(Long[] operIds) {
        return operLogMapper.deleteOperLogByIds(operIds);
    }

    /**
     * 查询操作日志详细
     *
     * @param operId 操作ID
     * @return 操作日志对象
     */
    @Override
    public SysOperOrderLog selectOperLogById(Long operId) {
        if (operId == null || operId <= 0) {
            // 处理无效输入，返回 null 或抛出自定义异常
            return null;
        }

        try {
            // 查询主日志信息
            SysOperOrderLog sysOperOrderLog = operLogMapper.selectOperLogById(operId);
            if (sysOperOrderLog == null) {
                // 如果主日志不存在，直接返回 null
                return null;
            }

            // 查询子日志详情描述
            List<String> detailDescList = fetchDetailDescListByParentId(operId);

            // 设置子日志详情描述到主日志对象中
            sysOperOrderLog.setDetailDesc(detailDescList);

            return sysOperOrderLog;
        } catch (Exception e) {
            // 捕获异常并记录日志，根据需求决定是否重新抛出
            e.printStackTrace();
            throw new RuntimeException("查询操作日志失败", e);
        }
    }

    /**
     * 根据父级 ID 查询子日志详情描述列表
     */
    private List<String> fetchDetailDescListByParentId(Long parentId) {
        List<SysOperOrderLog> detailList = operLogMapper.setDetailDescByParentId(parentId);
        if (detailList == null || detailList.isEmpty()) {
            return Collections.emptyList(); // 返回空列表以避免 NullPointerException
        }
        // 使用 Java 8 流式操作简化代码
        return detailList.stream()
                .map(SysOperOrderLog::getOperationDetail) // 提取 OperationDetail
                .filter(Objects::nonNull)                // 过滤掉 null 值
                .collect(Collectors.toList());           // 兼容低版本 Java 的 collect 方法

    }


    /**
     * 清空操作日志
     */
    @Override
    public void cleanOperLog() {
        operLogMapper.cleanOperLog();
    }

    /**
     * 根据主键查询订单头信息
     *
     * @param pkField   主键字段
     * @param tableName 表名
     * @param pkValue   主键值
     * @return 单据表头信息
     */
    @Override
    public Map<String, Object> selectOrderHeaderByPk(String pkField, String tableName, Object pkValue) {
        return operLogMapper.selectOrderHeaderByPk(pkField, tableName, pkValue);
    }

    /**
     * 根据主键查询订单头信息
     *
     * @param pkField   关联字段
     * @param tableName 表名
     * @param pkValue   关联字段值
     * @return 单据表头信息
     */
    @Override
    public List<Map<String, Object>> selectOrderDetailsByPk(String pkField, String tableName, Object pkValue) {
        return operLogMapper.selectOrderDetailsByPk(pkField, tableName, pkValue);
    }

    /**
     * 获取字段翻译
     *
     * @param tableName 表名
     * @return 字段翻译
     */
    @Override
    public List<Map<String, String>> getFieldTranslations(String tableName) {
        return operLogMapper.getFieldTranslations(tableName);
    }

    /**
     * 根据主键查询订单头信息
     *
     * @param pkField 主键字段
     * @param url     请求地址
     * @param pkValue 主键值
     * @return 单据表头信息
     */
    @Override
    public Map<String, Object> selectOldInfoByPk(String pkField, String url, Object pkValue) {
        HashMap<String, Object> queryMap = new HashMap<>();
        queryMap.put(pkField, pkValue);

        TableDataInfo tableDataInfo = fusionHttpUtils.getTableDataInfo(url, queryMap);
        List<?> rows = tableDataInfo.getRows();
        if (rows != null && !rows.isEmpty()) {
            return (Map<String, Object>) rows.get(0);
        }
        return Collections.emptyMap();
    }

    /**
     * restful风格查询新旧信息
     *
     * @param pkField 主键值
     * @param url     请求地址
     * @return 查询信息
     */
    @Override
    public Map<String, Object> selectGetRestFulApi(Object pkField, String url) {
        url = url.split("\\{")[0];
        AjaxResult ajaxResult = fusionHttpUtils.sendGetRestFulApi(url + pkField);
        if (ajaxResult.isSuccess()) {
            Object data = ajaxResult.get("data");
            if (data instanceof Map) {
                return (Map<String, Object>) data;
            }
        }
        return Collections.emptyMap();
    }

    /**
     * 解析JSON字符串
     *
     * @param json JSON字符串
     * @return 解析后的结果
     * @throws JsonProcessingException 处理JSON字符串时发生异常
     */
    public static String parseJson(String json) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {
        });

        // 判断是否为第二种格式（行号格式）
        boolean isLineFormat = map.keySet().stream().anyMatch(k -> k.startsWith("行号："));

        if (isLineFormat) {
            return processLineFormat(map);
        } else {
            return processSimpleFormat(map);
        }
    }

    // 处理第一种简单格式
    private static String processSimpleFormat(Map<String, Object> map) {
        List<String> results = new ArrayList<>();
        if (!map.isEmpty()) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                Map<String, String> valueMap = (Map<String, String>) entry.getValue();
                results.add(String.format("%s：由%s修改为%s",
                        entry.getKey(),
                        valueMap.get("oldValue"),
                        valueMap.get("newValue")));
            }
        }
        return String.join("\n", results);
    }

    // 处理第二种行号格式
    private static String processLineFormat(Map<String, Object> map) {
        StringBuilder result = new StringBuilder();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            // 解析行号信息
            String[] headerParts = entry.getKey().split("：");
            String lineNumber = headerParts[headerParts.length - 1];
            result.append("行号").append(lineNumber).append("：");

            // 处理明细字段
            List<String> details = new ArrayList<>();
            Map<String, Map<String, String>> lineValues = (Map<String, Map<String, String>>) entry.getValue();
            if (!lineValues.isEmpty()) {
                for (Map.Entry<String, Map<String, String>> field : lineValues.entrySet()) {
                    details.add(String.format("%s：由%s修改为%s",
                            field.getKey(),
                            field.getValue().get("oldValue"),
                            field.getValue().get("newValue")));
                }
            }
            result.append(String.join(";", details));
        }
        return result.toString();
    }
}
